﻿using System;
using System.Threading;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace PedesTrainProject.Traffic
{
    [Serializable()]
    public class PedestrianFlow : ISerializable
    {
        private List<Pedestrian> pedestrians;
        private Thread releaseThread;
        private Thread pedestriansThread;
        private Thread animateThread;
        List<int> available_tiles = new List<int>();

        private Core.ICoreTraffic coreTraffic;

        public PedestrianFlow(Core.ICoreTraffic _coreTraffic)
        {
            coreTraffic = _coreTraffic;

            pedestrians = new List<Pedestrian>();
            releaseThread = new Thread(releasePedestrians);
            pedestriansThread = new Thread(movePedestrians);
            animateThread = new Thread(animatePedestrians);

            Grid.Grid grid = coreTraffic.getGrid();
            for (int i = 0; i < grid.Tiles.Count; i++)
            {
                Grid.Tile tile = grid.Tiles[i];
                if (tile.Road.Name != "empty") available_tiles.Add(i);
            }

            //Console.WriteLine("Count: " + available_tiles.Count);

            //releaseThread.Start();
            //edestriansThread.Start();
            //animateThread.Start();
        }

        private void releasePedestrians()
        {
            while (true)
            {
                Random rand = new Random();
                int random = rand.Next(0, available_tiles.Count);
                lock (pedestrians)
                {
                    Pedestrian pedestrian = new Pedestrian(available_tiles[random], coreTraffic);
                    addPedestrian(pedestrian);
                }
                Thread.Sleep(1000);
            }
        }

        private void movePedestrians()
        {
            while (true)
            {
                lock (pedestrians)
                {
                    for (int i = 0; i < pedestrians.Count; i++)
                    {
                        bool move = pedestrians[i].move();
                        if (!move) removePedestrian(pedestrians[i]);
                    }
                }
                Thread.Sleep(500);
            }
        }

        private void animatePedestrians()
        {
            while (true)
            {
                lock (pedestrians)
                {
                    for (int i = 0; i < pedestrians.Count; i++) pedestrians[i].animate();
                }
                Thread.Sleep(500);
                coreTraffic.drawAll();
            }
        }

        public PedestrianFlow(List<Pedestrian> pedestrians)
        {

        }

        void addPedestrian(Pedestrian pedestrian)
        {
            pedestrians.Add(pedestrian);
        }

        void removePedestrian(Pedestrian pedestrian)
        {
            pedestrians.Remove(pedestrian);
        }

        public void run()
        {

        }

        public void pause()
        {

        }

        public void stop()
        {

        }

        #region Serialize
        public PedestrianFlow(SerializationInfo info, StreamingContext ctxt)
        {
            this.pedestrians = (List<Pedestrian>)info.GetValue("Pedestrian", typeof(List<Pedestrian>));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("Pedestrian", this.pedestrians);
        }
        #endregion
    }
}
